# -*- coding: utf-8 -*-
import datetimeimport randomimport jsonimport timeimport mod.server.extraServerApi as serverApifrom legendaryPowerScript._lpcommon.vector import Vectorfrom mod_log import loggerfrom legendaryPowerScript._lpcommon import apiUtil, vectorfrom legendaryPowerScript.quest.questManager import AcceptedQuest, KillQuestfrom .item.legendaryItem import LegendaryItemfrom .ui.confirmUI import ConfirmUI, ConfirmOptionimport base64import StringIOimport gzip# from legendaryPowerScript import creatures# from legendaryPowerScript.npc.npcManager import renderSettingdef getPlayerByUID(uid):
    # type: (int) -> PlayerStorage
    """
    根据UID获取玩家存储对象
    参数：
        - uid (int)：玩家UID
    返回：
        - playerStorage (PlayerStorage)：玩家存储对象或None
    """
    pass

class MoneyType:
    def __init__(self, id, data):
        """
        表示货币类型的类。

        Args:
            id (int): 货币类型的唯一标识符。
            data (dict): 包含货币类型相关信息的字典。

        Attributes:
            id (int): 货币类型的唯一标识符。
            displayName (str): 货币类型的显示名称，默认为"货币"。
            iconName (str): 货币类型的图标名称，默认为"货币"。
            display (bool): 是否显示货币类型，默认为True。
            sound (str): 播放声音的名称，默认为"random.toast"。
            pitch (float): 声音的音调，默认为1.0。
            texture (str or None): UI图标的纹理，默认为None。
            textureUV (list): UI图标的纹理坐标尺寸，默认为[64, 64]。
            iconType (ItemType): 货币类型对应的物品类型对象。

        """
        self.id = 0  # type: int
        self.displayName = ""  # type: str
        self.iconName = ""  # type: str
        self.display = False  # type: bool
        self.sound = ""  # type: str
        self.pitch = 0.0  # type: float
        self.texture = None  # type: str or None
        self.textureUV = []  # type: list
        self.iconType = ItemType()  # type: ItemType
        pass

    def getIcon(self, amount):
        # type: (int) -> LegendaryItem
        """
        获取货币类型对应的图标物品

        参数：
            - amount (int)：图标物品的数量

        返回：
            - icon (LegendaryItem)：图标物品实例
        """
        pass

    def getMoneyType(cls, id):
        # type: (int) -> MoneyType
        """
        获取指定ID的货币类型

        参数：
            - id (int/str)：货币类型ID

        返回：
            - moneyType (MoneyType)：货币类型对象或None
        """
        pass

class PlayerStorage:
    def __init__(self, creature):
        """
        用于存储玩家存档信息。可通过creature.playerStorage获取到该玩家的存档信息实例

        表示玩家存储的类。

        Args:
            creature (Creature): 玩家对应的实体。

        Attributes:
            creature (Creature): 玩家对应的实体。
            realm2ServerTypes (dict): 各个大区里上次退出的服务器类型。
            realm2Pos (dict): 各个大区里上次退出的位置。
            joinTime (long): 玩家加入游戏的时间戳。
            loadedInv (bool): 是否已加载物品栏。
            loadedData (bool): 是否已加载存档数据。
            inSafeZone (bool): 是否在安全区。
            inNoMagicZone (bool): 是否在禁魔区。
            askedDenyForever (bool): 是否此次登录永久不收队伍邀请。
            channelLoc (None or str): 玩家正在引导技能的目标位置，默认为None。
            uid (int): 玩家的唯一标识符。
            realmDesc (dict[int, str]): 玩家在各个大区的账号信息简介。
            activeSkills (dict[int, Skill]): 装备的技能，键为装备槽位，值为技能Skill。
            skills (dict[str, Skill]): 所有技能字典，键为技能名称，值为技能对象。
            activeQuest (list[AcceptedQuest]): 激活的任务列表。
            acceptedQuestNames (list[str]): 已接受的任务名称列表。
            finishedQuestNames (list[str]): 已完成的任务名称列表。
            saveLoc (dict[str, Vector]): 当前大区中，各个serverType上次退出的坐标。
            isPC (bool): 是否是PC玩家。
            inited (bool): 是否已初始化。
            money (dict[MoneyType, int]): 玩家拥有的货币类型和金额。
            skipSaveLoc (bool): 是否在退出时不会将位置保存进saveLoc中。
            navigatingQuest (None or AcceptedQuest): 正在导航的任务。
            miscData (dict): 各种杂项存档数据。默认值见 miscDefault
            storageKeys (set): 仓库中有保存的物品的名字。
            storage (list): 仓库中的物品。
            playTime (float): 玩家登录时间戳（time.time()）。
            questIcons (dict): 当前看到的NPC头顶任务图标的缓存。
            viewingMap (None or str): 正在查看的地图名字（MapInfo.getMapInfo(viewingMap)）。
            equippedItems (list[LegendaryItem]): 装备中的物品列表。注意是属性生效的装备。
            queuePackets (list): 队列中的包。在玩家阅读剧情时，播放的声音和信息会被拦截并存在这里，退出阅读剧情时会发送
            viewingConversation (bool): 是否正在查看任务剧情。
            deleted (bool): 是否已删除(玩家已离线)。
            loadFailed (bool): 加载存档失败时，变为True。
            teleported (bool): 是否玩家在登录时已被传送到出生点。
            askedTeleport (Quest or None): 玩家完成任务时，询问玩家是否要传送到完成地点的任务。
            protocol (None or str): 玩家所使用的客户端版本号。
            lastSyncRenderSetting (dict): 上次同步实体渲染设置的字典。
            shopNewsCache (dict): 商店“新”状态的缓存。
            backLocation (None or Vector): 玩家上次传送前（间距大于10格）的位置。默认为None。
            activeZones (bool): 关闭后，不会判断触发区域。在登录加载完成后自动设为True
            onSwapWorldCompleteCmd (list): 在切换世界完成时，会执行这些指令。
            spellGraphicCache (set): 上次向玩家客户端同步的魔法的特效版本缓存。
            boundName (bool): 是否玩家已完成实名认证。
            boundPhone (bool): 是否已绑定手机号。
            isVIP (bool): 是否是启动器的VIP。
        """
        self.creature = Creature()  # type: Creature
        self.realm2ServerTypes = {}  # type: dict
        self.realm2Pos = {}  # type: dict
        self.joinTime = long()  # type: long
        self.loadedInv = False  # type: bool
        self.loadedData = False  # type: bool
        self.inSafeZone = False  # type: bool
        self.inNoMagicZone = False  # type: bool
        self.askedDenyForever = False  # type: bool
        self.channelLoc = ""  # type: None or str
        self.uid = 0  # type: int
        self.realmDesc = {}  # type: dict[int, str]
        self.activeSkills = {}  # type: dict[int, Skill]
        self.skills = {}  # type: dict[str, Skill]
        self.activeQuest = []  # type: list[AcceptedQuest]
        self.acceptedQuestNames = []  # type: list[str]
        self.finishedQuestNames = []  # type: list[str]
        self.saveLoc = {}  # type: dict[str, Vector]
        self.isPC = False  # type: bool
        self.inited = False  # type: bool
        self.money = {}  # type: dict[MoneyType, int]
        self.skipSaveLoc = False  # type: bool
        self.navigatingQuest = None or AcceptedQuest()  # type: None or AcceptedQuest
        self.miscData = {}  # type: dict
        self.storageKeys = set()  # type: set
        self.storage = []  # type: list
        self.playTime = 0.0  # type: float
        self.questIcons = {}  # type: dict
        self.viewingMap = ""  # type: None or str
        self.equippedItems = []  # type: list[LegendaryItem]
        self.queuePackets = []  # type: list
        self.viewingConversation = False  # type: bool
        self.deleted = False  # type: bool
        self.loadFailed = False  # type: bool
        self.teleported = False  # type: bool
        self.askedTeleport = None  # type: Quest or None
        self.protocol = ""  # type: None or str
        self.lastSyncRenderSetting = {}  # type: dict
        self.shopNewsCache = {}  # type: dict
        self.backLocation = None or Vector()  # type: None or Vector
        self.activeZones = False  # type: bool
        self.onSwapWorldCompleteCmd = []  # type: list
        self.spellGraphicCache = set()  # type: set
        self.boundName = False  # type: bool
        self.boundPhone = False  # type: bool
        self.isVIP = False  # type: bool
        pass

    def activateZones(self):
        # type: () -> None
        """
        令玩家可以触发“触发区域”。在完成登录加载后自动调用

        参数：
            无

        返回：
            无
        """
        pass

    def openSetting(self):
        # type: () -> None
        """
        打开设置

        参数：
            无

        返回：
            无
        """
        pass

    def setModel(self, model):
        # type: (str) -> None
        """
        替换骨骼模型。会被持久化保存在存档里
        参数：
            - model (str)：模型在netease_models.json中注册的名称
        返回：
            无
        """
        pass

    def AddExp(self, exp, dropByLevel=True):
        # type: (int, bool) -> float
        """
        添加经验值。经验达到上限后会提升等级

        参数：
            - exp (int)：经验值数量
            - dropByLevel (bool)：是否受item/config.yml中的等级经验倍率影响，默认为True

        返回：
            - result (float)：最终获得的经验值
            - displayedMultiplier (float)：显示的倍率
        """
        pass

    def SetExp(self, exp):
        # type: (int) -> None
        """
        设置当前RPG等级的经验值百分比

        参数：
            - exp (int)：经验值百分比

        返回：
            无
        """
        pass

    def startTutorial(self, cg, text, entryText):
        # type: (str, str, str) -> None
        """
        开始教程。玩家屏幕中下方会出现一个问号，点击后打开教程界面，显示图片和文字

        参数：
            - cg (str)：教程图片(textures/ui/tutorial下的相对路径）
            - text (str)：教程文本
            - entryText (str)：屏幕按钮的显示文本

        返回：
            无
        """
        pass

    def endTutorial(self):
        # type: () -> None
        """
        结束教程（玩家屏幕下方的那个问号按钮）

        参数：
            无

        返回：
            无
        """
        pass

    def resetInvMaxSize(self):
        # type: () -> None
        """
        刷新背包最大容量

        参数：
            无

        返回：
            无
        """
        pass

    def resetManaExpand(self):
        # type: () -> None
        """
        刷新基础魔力

        参数：
            无

        返回：
            无
        """
        pass

    def getPlayTime(self):
        # type: () -> float
        """
        获取今日在线时间

        参数：
            - 无

        返回：
            - playTime (float)：游戏时间
        """
        pass

    def _updateExp(self):
        # type: () -> None
        """
        更新经验值

        参数：
            - 无

        返回：
            - 无
        """
        pass

    def _getVanillaMaxExp(self):
        # type: () -> int
        """
        获取原版最大经验值

        参数：
            - 无

        返回：
            - maxExp (int)：原版最大经验值
        """
        pass

    def refreshRealmDesc(self):
        # type: () -> list
        """
        刷新境界描述

        参数：
            - 无

        返回：
            - desc (list)：境界描述列表
        """
        pass

    def SetLevel(self, level):
        # type: (int) -> None
        """
        设置等级

        参数：
            - level (int)：等级

        返回：
            - 无
        """
        pass

    def SetElitePossibility(self, possibility, increaseCount=False):
        # type: (float, bool) -> None
        """
        设置精英怪出现概率

        参数：
            - possibility (float)：精英怪出现概率
            - increaseCount (bool)：是否增加计数

        返回：
            - 无
        """
        pass

    def resetQuests(self, keyword):
        # type: (str) -> list
        """
        重置任务

        参数：
            - keyword (str)：任务关键词

        返回：
            - notified (list)：重置的任务列表
        """
        pass

    def GetMaxExp(self):
        # type: () -> int
        """
        获取最大经验值

        参数：
            - 无

        返回：
            - maxExp (int)：最大经验值
        """
        pass

    def GetMoney(self, moneyType):
        # type: (int or MoneyType) -> int
        """
        获取金钱数量

        参数：
            - moneyType (int or MoneyType)：金钱类型

        返回：
            - money (int)：金钱数量
        """
        pass

    def HasMoney(self, moneyType, amount):
        # type: (int or MoneyType, int) -> bool
        """
        判断是否拥有足够的金钱

        参数：
            - moneyType (int or MoneyType)：金钱类型
            - amount (int)：金钱数量

        返回：
            - hasMoney (bool)：是否拥有足够的金钱
        """
        pass

    def TakeMoney(self, moneyType, amount):
        # type: (int, int) -> object
        """
        扣除金钱

        参数：
            - moneyType (int or MoneyType)：金钱类型
            - amount (int)：金钱数量

        返回：
            - 无
        """
        pass

    def SetMoney(self, moneyType, amount):
        # type: (int or MoneyType, int) -> None
        """
        设置金钱数量

        参数：
            - moneyType (int or MoneyType)：金钱类型
            - amount (int)：金钱数量

        返回：
            - 无
        """
        pass

    def GiveMoney(self, moneyType, amount, suffix="", changeVariable=True):
        # type: (int or MoneyType, int, str, bool) -> None
        """
        给予金钱

        参数：
            - moneyType (int or MoneyType)：金钱类型
            - amount (int)：金钱数量
            - suffix (str)：提示信息的后缀，默认空
            - changeVariable (bool)：是否改变“mhistory_金钱ID”变量，默认True

        返回：
            - 无
        """
        pass

    def sendDamageText(self, text, boundEntity, source, velocity, gravity=0.1, depth=False, font=3, id=None):
        # type: (str, str, Vector, Vector, float, optional, bool, optional, int, optional, str, optional) -> None
        """
        发送浮空伤害数字

        参数：
            - text (str)：要显示的字符
            - boundEntity (str)：受到伤害的实体的id
            - source (Vector)：产生伤害的实体位置
            - velocity (Vector)：伤害数字位移速度
            - gravity (float, optional)：伤害数字下落速度，默认为0.1
            - depth (bool, optional)：伤害数字是否显示在实体后面，默认为False
            - font (int, optional)：伤害数字字体大小，默认为3
            - id (str, optional)：事件id，默认为 None

        返回：
            无
        """
        pass

    def sendHologram(self, id, text, location, fontSize):
        # type: (str, str, tuple or Vector, float) -> None
        """
        发送浮空字

        参数：
            - id (str)：事件id
            - text (str)：要显示的字符
            - location (tuple or Vector)：位置
            - fontSize (float)：字体大小

        返回：
            无
        """
        pass

    def openStorage(self):
        # type: () -> None
        """
        打开仓库
        参数：
            无
        返回：
            无
        """
        pass

    def viewStorageInText(self, creature, name, prefix=""):
        # type: (Creature or ConsoleSender or MasterSender, str, str, optional) -> None
        """
        在将仓库信息用文字打印出来

        参数：
            - creature (Creature or ConsoleSender or MasterSender)：信息接收者
            - name (str)：仓库名
            - prefix (str, optional)：前缀，默认为空

        返回：
            无
        """
        pass

    def viewStorageItem(self, index):
        # type: (int) -> None
        """
        查看某一项仓库物品

        参数：
            - index (int)：仓库物品索引

        返回：
            无
        """
        pass

    def takeItemFromStorage(self, index, amount):
        # type: (int, int) -> None
        """
        从仓库中取出物品

        参数：
            - index (int)：仓库物品索引
            - amount (int)：数量

        返回：
            无
        """
        pass

    def getStorageAmount(self):
        # type: () -> float
        """
        获取仓库内物品总重量

        参数：
            无

        返回：
            - amount (float)：物品总重量
        """
        pass

    def addItemToStorage(self, slot, amount=999, checkFull=True):
        # type: (object or int, int, optional, bool, optional) -> None
        """
        向仓库添加物品

        参数：
            - slot (object or int)：物品对象或者物品所在背包的槽位
            - amount (int, optional)：数量，默认为999
            - checkFull (bool, optional)：是否检查仓库是否已满，默认为True

        返回：
            无
        """
        pass

    def onNewDay(self):
        # type: () -> None
        """
        每天第一次登录时自动触发

        参数：
            无

        返回：
            无
        """
        pass

    def updateHUD(self, init=True):
        # type: () -> None
        """
        玩家刷新UI界面时自动触发

        参数：
            无

        返回：
            无
        """
        pass

    def OnKill(self, creature, callMembers=True):
        # type: (Creature, bool) -> 无返回值
        """
        击杀实体时，推进击杀任务

        参数：
            - creature (Creature)：被击杀的角色对象
            - callMembers (bool)：是否调用组队成员的击杀事件处理函数，默认为True

        返回：
            无返回值
        """
        pass

    def OnKillName(self, victimName, count=1):
        # type: (str, int) -> 无返回值
        """
        击杀指定名称实体时，推进击杀任务

        参数：
            - victimName (str)：被击杀角色的名称
            - count (int)：击杀数量，默认为1

        返回：
            无返回值
        """
        pass

    def updateMoney(self):
        # type: (无参数) -> 无返回值
        """
        更新金钱信息

        参数：
            无参数

        返回：
            无返回值
        """
        pass

    def savePlayerData(self):
        # type: (无参数) -> 无返回值
        """
        保存玩家数据

        参数：
            无参数

        返回：
            无返回值
        """
        pass

    def acceptQuest(self, quest, giveReward=True, sender=None):
        # type: (Quest, bool) -> Conversation
        """
        接受任务

        参数：
            - quest (Quest)：任务对象
            - giveReward (bool)：是否给予奖励，默认为True

        返回：
            - conversation (Conversation)：任务对话框对象
        """
        pass

    def EquipSkill(self, slot, skill):
        # type: (int, Skill) -> None
        """
        装备技能。
        技能槽位有：
        0-9：主动技能
        10：终极技能
        20或以上：被动技能

        参数：
            - slot (int)：技能槽位
            - skill (Skill)：要装备的技能

        返回：
            - 无
        """
        pass

    def EquipDomain(self, slot, skill, multiSkillIndex):
        # type: (int, Skill) -> None
        """
        装备技能。
        技能槽位有：
        0-9：主动技能
        10：终极技能
        20或以上：被动技能

        参数：
            - slot (int)：技能槽位
            - skill (Skill)：要装备的技能

        返回：
            - 无
        """
        pass

    def sendCooldown(self, spell, untilTime, fromTime=None, isDuration=False):
        # type: (str/int/Skill, float, float) -> None
        """
        更新客户端的技能冷却。

        参数：
            - spell (str/int/Skill)：技能名或技能对象
            - untilTime (float)：冷却时间截止时间
            - fromTime (float)：冷却时间起始时间，默认为None

        返回：
            - 无
        """
        pass

    def viewWarSoul(self, viewing=None):
        # type: (str) -> 无返回值
        """
        获取并显示斗魂技能信息。

        参数：
            - viewing (str)：查看的技能名称（可选）。

        返回：
            无返回值。
        """
        pass

    def OpenDomain(self, viewing=None):
        # type: (str) -> 无返回值
        """
        获取并显示斗魂技能信息。

        参数：
            - viewing (str)：查看的技能名称（可选）。

        返回：
            无返回值。
        """
        pass

    def viewSmzySkill(self, viewing=None):
        # type: (str) -> 无返回值
        """
        获取并显示神魔战域技能信息（每个技能单独安装宝石，安装后常驻生效）

        参数：
            - viewing (str)：查看的技能名称（可选）。

        返回：
            无返回值。
        """
        pass

    def isSkillActive(self, name):
        # type: (str) -> bool
        """
        检查指定名称的技能是否正在使用中。

        参数：
            - name (str)：技能名称。

        返回：
            - result (bool)：技能是否正在使用中。
        """
        pass

    def updateSkills(self, force=False):
        # type: (bool) -> 无返回值
        """
        更新技能信息并向客户端发送更新。

        参数：
            - force (bool)：是否强制更新所有技能（默认为False）。

        返回：
            无返回值。
        """
        pass

    def GetSkill(self, name):
        # type: (str) -> ItemType
        """
        根据技能名获取技能类型对象。

        参数：
            - name (str)：技能名。

        返回：
            - (ItemType)：技能类型对象，如果不存在返回None。
        """
        pass

    def viewSkills(self, viewing=None):
        # type: (str) -> 无返回值
        """
        查看技能列表或打开特定视图。

        参数：
            - viewing (str)：所要查看的特定技能名（默认为None）。

        返回：
            无返回值。
        """
        pass

    def viewDomain(self, viewing=None):
        # type: (str) -> 无返回值
        """
        查看技能列表或打开特定视图。

        参数：
            - viewing (str)：所要查看的特定技能名（默认为None）。

        返回：
            无返回值。
        """
        pass

    def OpenSkillList(self, viewing=None):
        # type: (str) -> 无返回值
        """
        打开技能列表。

        参数：
            - viewing (str)：所要查看的特定技能名（默认为None）。

        返回：
            无返回值。
        """
        pass

    def getActiveIndex(self, q):
        # type: (str/unicode) -> int
        """
        获取给定任务名称所对应的在任务列表中的索引位置
        参数：
            - q (str/unicode)：任务名称或者任务对象

        返回：
            - index (int)：任务名称所对应的在任务列表中的索引位置
        """
        pass

    def finishQuest(self, index):
        # type: (int) -> 无返回值
        """
        完成指定索引位置的任务，并领取任务奖励

        参数：
            - index (int)：任务在任务列表中的索引位置

        返回：
            - 无返回值
        """
        pass

    def removeQuest(self, index, reopen=False):
        # type: (int, bool) -> AcceptedQuest
        """
        从任务列表中移除指定索引位置的任务

        参数：
            - index (int)：任务在任务列表中的索引位置
            - reopen (bool)：是否重新打开任务列表，如果为True，则会重新打开任务列表

        返回：
            - quest (AcceptedQuest)：被移除的任务对象，如果任务不存在，则返回None
        """
        pass

    def setNavigating(self, quest):
        # type: (AcceptedQuest) -> None
        """
        设置当前正在进行的导航任务

        参数：
            - quest (AcceptedQuest)：导航任务对象

        返回：
            - 无返回值
        """
        pass

    def switchPvp(self, isCommand=False, confirm=False):
        # type: (bool, bool) -> 无返回值
        """
        切换PVP模式（普通模式和杀戮模式之间）

        参数：
            - isCommand (bool)：是否是通过命令切换PVP模式，如果是则为True
            - confirm (bool)：是否需要二次确认，如果需要则为True

        返回：
            - 无返回值
        """
        pass

    def broadcastFightMode(self, isFree):
        # type: (bool) -> 无返回值
        """
        广播个人战斗模式状态（主要用于PVP）

        参数：
            - isFree (bool)：是否处于自由战斗模式，如果是则为True

        返回：
            - 无返回值
        """
        pass

    def handlePCPE(self, messages):
        # type: (list) -> list
        """
        处理PCPE消息，将PCPE占位符替换为对应的文本

        参数：
            - messages (list)：待处理的消息列表

        返回：
            - cloned (list)：处理后的消息列表
        """
        pass

    def hasQuest(self, questName, requireFinished):
        # type: (str, bool) -> bool
        """
        判断是否存在指定名称的任务

        参数：
            - questName (str)：任务名称
            - requireFinished (bool)：是否需要判断任务是否已经完成，如果需要则为True

        返回：
            - exist (bool)：是否存在指定名称的任务
        """
        pass

    def viewQuests(self):
        # type: (无参数) -> @return
        """
        查看任务列表，将任务信息发送给客户端进行显示

        参数：
            - 无参数

        返回：
            - 无返回值
        @return:
        """
        pass

    def gzip_zip_base64(cls, content):
        # type: () -> None
        """
        gzip+base64压缩
            这种方式在压缩对象比较短/小的时候效果并不明显，因为base64之后反而会变大，但是压缩对象比较大时才有效果
        :param content:
        :return:
        """
        pass

    def gzip_unzip_base64(cls, content):
        # type: () -> None
        """
        base64+gzip解压
        :param content:
        :return:
        """
        pass

